package com.git.hui.yinshua.biz.goods.service.convert;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.git.hui.yinshua.api.model.constants.GlobalConstants;
import com.git.hui.yinshua.biz.goods.dao.domain.CategoryEntity;
import com.git.hui.yinshua.biz.goods.dao.domain.GoodsAttributeKeyEntity;
import com.git.hui.yinshua.biz.goods.dao.domain.GoodsAttributeValueEntity;
import com.git.hui.yinshua.biz.goods.dao.domain.GoodsDetailEntity;
import com.git.hui.yinshua.biz.goods.dao.domain.GoodsEntity;
import com.git.hui.yinshua.biz.goods.dao.domain.GoodsSpecEntity;
import com.git.hui.yinshua.biz.rest.models.goods.rsp.AttrKeyDto;
import com.git.hui.yinshua.biz.rest.models.goods.rsp.AttrValDto;
import com.git.hui.yinshua.biz.rest.models.goods.rsp.CategoryDto;
import com.git.hui.yinshua.biz.rest.models.goods.rsp.GoodsDetailDto;
import com.git.hui.yinshua.biz.rest.models.goods.rsp.GoodsInfoDto;
import com.git.hui.yinshua.biz.rest.models.goods.rsp.GoodsSpecDto;
import com.git.hui.yinshua.biz.rest.models.goods.rsp.GoodsSpecItem;
import com.git.hui.yinshua.biz.util.ImgUtil;
import com.git.hui.yinshua.biz.util.PriceUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author YiHui
 * @date 2024/6/12
 */
public class GoodsConvert {

    public static CategoryDto toCategory(CategoryEntity entity) {
        CategoryDto dto = new CategoryDto();
        dto.setCid(entity.getId());
        dto.setCategory(entity.getCategory())
                .setIntro(entity.getIntro())
                .setState(entity.getState())
                .setCreateAt(entity.getCreateAt())
                .setSort(entity.getSort());
        return dto;
    }

    public static List<CategoryDto> batchToCategory(List<CategoryEntity> list) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().map(GoodsConvert::toCategory).collect(Collectors.toList());
    }

    public static AttrKeyDto toKey(GoodsAttributeKeyEntity entity) {
        AttrKeyDto dto = new AttrKeyDto();
        dto.setKey(entity.getAttributeName());
        dto.setUnit(entity.getAttributeUnit());
        dto.setKeyId(entity.getId());
        dto.setCid(entity.getCategoryId());
        return dto;
    }

    public static List<AttrKeyDto> batchToKey(List<GoodsAttributeKeyEntity> list) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().map(GoodsConvert::toKey).collect(Collectors.toList());
    }

    public static AttrValDto toVal(GoodsAttributeValueEntity entity) {
        AttrValDto dto = new AttrValDto();
        dto.setKeyId(entity.getAttributeId());
        dto.setValue(entity.getAttributeValue());
        dto.setValId(entity.getId());
        return dto;
    }

    public static List<AttrValDto> batchToVal(List<GoodsAttributeValueEntity> list) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().map(GoodsConvert::toVal).collect(Collectors.toList());
    }

    public static GoodsDetailDto toDetail(GoodsDetailEntity entity) {
        GoodsDetailDto detail = new GoodsDetailDto();
        detail.setDetailId(entity.getId());
        detail.setSort(entity.getSort());
        detail.setIntro(entity.getIntro());
        detail.setTitle(entity.getTitle());
        detail.setImgs(ImgUtil.toImgList(entity.getImgs()));
        return detail;
    }

    public static List<GoodsDetailDto> batchToDetails(List<GoodsDetailEntity> list) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<GoodsDetailDto> ans = list.stream().map(GoodsConvert::toDetail).collect(Collectors.toList());
        Collections.sort(ans, Comparator.comparingInt(GoodsDetailDto::getSort));
        return ans;
    }

    public static GoodsSpecDto toSpec(GoodsSpecEntity entity) {
        GoodsSpecDto spec = new GoodsSpecDto();
        spec.setSpecId(entity.getId());
        spec.setSpec(entity.getGoodsSpecs());
        spec.setPrice(PriceUtil.toYuanPrice(entity.getGoodsPrice()));
        spec.setDiscountPrice(PriceUtil.toYuanPrice(entity.getDiscountPrice()));
        if (Objects.equals(spec.getDiscountPrice(), spec.getPrice())) {
            spec.setDiscountPrice(null);
        }
        spec.setMinCnt(entity.getMinCnt());
        spec.setStock(entity.getGoodsStock() < 0 ? GlobalConstants.GoodsApi.NO_LIMIT_STOCK : entity.getGoodsStock());
        spec.setSalesCnt(entity.getSalesCnt());
        spec.setPtEnable(Objects.equals(entity.getPtEnable(), GlobalConstants.GoodsApi.PT_ENABLE));
        spec.setPtNum(entity.getPtNum());
        spec.setPtTimePeriod(entity.getPtTimePeriod());
        if (StringUtils.isNotBlank(entity.getGoodsSpecs())) {
            JSONArray ary = JSONArray.parseArray(entity.getGoodsSpecs());
            List<GoodsSpecItem> items = new ArrayList<>();
            for (Object o : ary) {
                JSONObject obj = (JSONObject) o;
                GoodsSpecItem item = new GoodsSpecItem();
                item.setKeyId(obj.getInteger("keyId"));
                item.setKey(obj.getString("key"));
                item.setValueId(obj.getInteger("valueId"));
                item.setValue(obj.getString("value"));
                item.setUnit(obj.getString("unit"));
                items.add(item);

                if ("尺寸".equals(item.getKey())) {
                    String[] cells = item.getValue().split("x");
                    Integer w = Integer.valueOf(cells[0].trim());
                    Integer h = Integer.valueOf(cells[1].trim());
                    spec.setSizeW(w);
                    spec.setSizeH(h);
                }
            }
            spec.setSpecItems(items);
        }
        return spec;
    }

    public static List<GoodsSpecDto> batchToSpecs(List<GoodsSpecEntity> list) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream().map(GoodsConvert::toSpec).collect(Collectors.toList());
    }

    public static GoodsInfoDto toGoodsInfo(GoodsEntity goodsEntity, Function<Integer, String> cnameFunc) {
        GoodsInfoDto info = new GoodsInfoDto();
        info.setGoodsId(goodsEntity.getId());
        info.setCid(goodsEntity.getCategoryId());
        if (cnameFunc != null) {
            info.setCategory(cnameFunc.apply(goodsEntity.getCategoryId()));
        }
        info.setName(goodsEntity.getGoodsName());
        info.setPrice(PriceUtil.toYuanPrice(goodsEntity.getPrice()));
        info.setDiscountPrice(PriceUtil.toYuanPrice(goodsEntity.getDiscountPrice()));
        if (Objects.equals(info.getPrice(), info.getDiscountPrice())) {
            info.setDiscountPrice(null);
        }
        info.setMinCnt(goodsEntity.getMinCnt());
        info.setSalesCnt(goodsEntity.getSalesCnt());
        info.setIntro(goodsEntity.getIntro());
        info.setState(goodsEntity.getState());
        info.setRecommend(goodsEntity.getRecommend());
        info.setCreateAt(goodsEntity.getCreateAt());
        info.setUpdateAt(goodsEntity.getUpdateAt());
        info.setPublishAt(goodsEntity.getPublishAt());
        info.setThumbs(ImgUtil.toImgList(goodsEntity.getThumb()));
        info.setDetailList(batchToDetails(goodsEntity.getDetailList()));
        info.setSpecList(batchToSpecs(goodsEntity.getSpecList()));
        info.setPtEnable(Objects.equals(goodsEntity.getPtEnable(), GlobalConstants.GoodsApi.PT_ENABLE));
        if (!CollectionUtils.isEmpty(info.getSpecList())) {
            // 拼团信息，以第一个sku上的为准
            info.setPtNum(info.getSpecList().get(0).getPtNum());
            info.setPtTimePeriod(info.getSpecList().get(0).getPtTimePeriod());
        } else {
            // 没有尺寸的拼图，直接使用商品上的拼团信息
            info.setPtNum(goodsEntity.getPtNum());
            info.setPtTimePeriod(goodsEntity.getPtTimePeriod());
        }
        info.setPayExpireMin((int) (GlobalConstants.OrderApi.PAY_INTERVAL_TIME / 60_000L));
        return info;
    }

    public static List<GoodsInfoDto> batchToGoodsInfo(List<GoodsEntity> list, Function<Integer, String> cnameFunc) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }

        return list.stream().map(s -> toGoodsInfo(s, cnameFunc)).collect(Collectors.toList());
    }
}
